2009 年提出的包含模块、文件、 IO 、控制台在哪的一系列标准。在 Node.js 中实现了采用 CommonJS 标准的一部分。
每一个模块有自己单独的作用域。
通过 module.exports 导出模块中的内容:
module.exports = {
a: '',
b: function () {
console.log(this.a);
},
};
通过 require 模块进行模块导入, require 模块仅被执行一次。
在 2015 年提出了 Module ,将 import 和 export 作为保留字加入。 ES6 Modules 会自动采用严格模式。
导出分为命名导出和默认导出。
在声明时导出:
export const Pai = 3.1415926; // 命名导出
export default 'i am a string of this module default export'; // 默认导出;
先声明后导出:
const Pai = 3.1415926;
const Str = 'i am a nonsense';
export { Pai, Str };
与命名导出不一样,默认导出只有一个。
使用 import 进行导入。
import {a ,b } from 'model';
import {a ,b as c } from 'model';
import \* as allModel from 'model';
import {default as a, b} from 'modelA'; import c ,{d} from 'modelC';
在将一个模块导入后立即导出:
export { a, b } from 'modelA';
复合写法只针对命名导出,默认导出需要先导入后导出。
CommonJS 与 ES6 Module 最本质的区别在于前者对模块依赖的解决是“动态的”,而后者是“静态的”。在这里“动态”的含义是,模块依赖关系的建立发生在代码运行阶段;而“静态”则是模块依赖关系的建立发生在代码编译阶段。
require 的模块路径可以动态指定,支持传入一个表达式,我们甚至可以通过 if 语句判断是否加载某个模块。因此,在 CommonJS 模块被执行前,并没有办法确定明确的依赖关系,模块的导入、导出发生在代码的运行阶段。
ES6 Module 的导入、导出语句都是声明式的,它不支持导入的路径是一个表达式,并且导入、导出语句必须位于模块的顶层作用域(比如不能放在 if 语句中)。
死代码检测和排除。我们可以用静态分析工具检测出哪些模块没有被调用过。比如,在引入工具类库时,工程中往往只用到了其中一部分组件或接口,但有可能会将其代码完整地加载进来。未被调用到的模块代码永远不会被执行,也就成为了死代码。通过静态分析可以在打包时去掉这些未曾使用过的模块,以减小打包资源体积
模块变量类型检查。 JavaScript 属于动态类型语言,不会在代码执行前检查类型错误(比如对一个字符串类型的值进行函数调用)。 ES6 Module 的静态模块结构有助于确保模块之间传递的值或接口类型是正确的
编译器优化。在 CommonJS 等动态模块系统中,无论采用哪种方式,本质上导入的都是一个对象,而 ES6 Module 支持直接导入变量,减少了引用层级,程序效率更高
在导入一个模块时,对于 CommonJS 来说获取的是一份导出值的拷贝;而在 ES6 Module 中则是值的动态映射,并且这个映射是只读的。
简单说,就像简单值和引用值的关系。
直接导入即可。
AMD (异步模块)采用 define 函数来定义模块:
define('ID', ['modelA'], function (a) {
return function (b, c) {
console.log(`sum: ${modelA.add(b + c)}`);
};
});
在 AMD 中使用 define 函数来定义模块,它可以接受3个参数。第1个参数是当前模块的 id ,相当于模块名;第2个参数是当前模块的依赖,比如上面我们定义的 getSum 模块需要引入 calculator 模块作为依赖;第3个参数用来描述模块的导出值,可以是函数或对象。如果是函数则导出的是函数的返回值;如果是对象则直接导出对象本身。
导入:
require(['ID'], function (ID) {
ID(2, 3);
});
使用 npm 导入方法导入:
npm i -s {model name};